#pragma once
#include<iostream>
#include<string>
#include<memory>
#include<jsoncpp/json/json.h>

static const std::string sep="\r\n";

//"len"\r\n"jsonstr"\r\n
//添加报头
std::string Encode(const std::string &jsonstr)
{
    int len=jsonstr.size();
    std::string lenstr=std::to_string(len);
    return lenstr+sep+jsonstr+sep;
}
//不能加const
std::string Decode(std::string &packagestream)  //返回不为空时一定是一个完整字符串
{
    // 分析
    auto pos=packagestream.find(sep);
    if(pos==std::string::npos) return std::string(); //此时读的情况为："len、"len"、"len\r
    std::string lenstr=packagestream.substr(0,pos);
    int len=std::stoi(lenstr);
    int total=lenstr.size()+len+2*sep.size(); //一个完整报文长度
    if(packagestream.size()<total) return std::string(); //此时报文不完整，继续等待

    //此时至少有一个完整的报文，进行提取
    std::string jsonstr=packagestream.substr(pos+sep.size(),len);
    packagestream.erase(0,total); //将已经提取出来的的完整字符串删除，继续处理后续字符串
    return jsonstr;
}

class Request
{
public:
    Request(int x,int y,char oper)
        :_x(x)
        ,_y(y)
        ,_oper(oper)
    {

    }

    Request()
    {}

    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["x"]=_x;
        root["y"]=_y;
        root["oper"]=_oper;
        Json::FastWriter writer;
        //Json::StyledWriter writer;
        std::string s=writer.write(root);

        *out=s;
        return true;
    }

    bool Deserialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res=reader.parse(in,root);

        _x=root["x"].asInt();
        _y=root["y"].asInt();
        _oper=root["oper"].asInt();

        return true;
    }

    void Print()
    {
        std::cout<<_x<<std::endl;
        std::cout<<_y<<std::endl;
        std::cout<<_oper<<std::endl;
    }

    ~Request()
    {}

    int X()
    {
        return _x;
    }
    int Y()
    {
        return _y;
    }
    char Oper()
    {
        return _oper;
    }

    void SetValue(int x,int y,char oper)
    {
        _x=x;
        _y=y;
        _oper=oper;
    }

private:
    int _x;
    int _y;
    char _oper;
};

class Response
{
public:
    Response():_result(0),_code(0),_desc("success")
    {}

    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["result"]=_result;
        root["code"]=_code;
        root["desc"]=_desc;
        Json::FastWriter writer;
        //Json::StyledWriter writer;
        std::string s=writer.write(root);

        *out=s;
        return true;
    }
    bool Deserialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res=reader.parse(in,root);
        if(!res) return false;
        _result=root["result"].asInt();
        _code=root["code"].asInt();
        _desc=root["desc"].asString();

        return true;
    }

    void PrintResult()
    {
        std::cout<<"result: "<<_result<<" , code: "<<_code<<" , desc: "<<_desc<<std::endl;
    }

    ~Response()
    {}

public:
    int _result;
    int _code; //0:success , 1:div zero , 2:非法操作
    std::string _desc;
};

//工厂模式
class Factory
{
public:
    static std::shared_ptr<Request> BuildRequestDefault()
    {
        return std::make_shared<Request>();
    }

    static std::shared_ptr<Response> BuildResponseDefault()
    {
        return std::make_shared<Response>();
    }
};